package com.knife.hospital.service.order;

import com.knife.hospital.config.BaseException;
import com.knife.hospital.constant.ResponseCode;
import com.knife.hospital.constant.TimeQuantumEnum;
import com.knife.hospital.entity.ArrangementPO;
import com.knife.hospital.entity.DoctorPO;
import com.knife.hospital.entity.OrderPO;
import com.knife.hospital.entity.UserPO;
import com.knife.hospital.mapper.ArrangementPOMapper;
import com.knife.hospital.mapper.DoctorPOMapper;
import com.knife.hospital.mapper.OrderPOMapper;
import com.knife.hospital.mapper.UserPOMapper;
import com.knife.hospital.model.order.OrderRequest;
import com.knife.hospital.model.order.UserOrderResponse;
import com.knife.hospital.util.order.UserOrderUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class UserOrderServiceImpl implements UserOrderService {
    @Resource
    private OrderPOMapper orderPOMapper;
    @Resource
    private UserOrderUtil userOrderUtil;
    @Resource
    private ArrangementPOMapper arrangementPOMapper;
    @Resource
    private UserPOMapper userPOMapper;
    @Resource
    private DoctorPOMapper doctorPOMapper;

    @Override
    public List<UserOrderResponse> getUserOrders(int id) {
        try {
            List<OrderPO> userOrderPOs = orderPOMapper.getUserOrdersByPatientId(id);
            List<UserOrderResponse> userOrderResponses = userOrderPOs.stream().
                    map(userOrderUtil::orderPoToUserOrderResponse).collect(Collectors.toList());
            return userOrderResponses;
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    }

    @Override
    @Transactional
    public OrderPO applyOrder(OrderRequest orderRequest) {
        /**
         * 首先校验是否仍有余量
         */
        ArrangementPO arrangementPO;
        try {
            UserPO userPO = userPOMapper.selectByPrimaryKey(orderRequest.getPatientId());
            DoctorPO doctorPO = doctorPOMapper.selectByPrimaryKey(orderRequest.getDoctorId());
            if(Objects.isNull(userPO) || Objects.isNull(doctorPO))
                throw new BaseException(ResponseCode.OPERATION_FAILED);
            arrangementPO = arrangementPOMapper.selectByDoctorIdAndDate(
                    orderRequest.getDoctorId(), orderRequest.getDate());
        } catch (Exception e) {
            throw new BaseException(ResponseCode.OPERATION_FAILED);
        }
        if (Objects.isNull(arrangementPO))
            throw new BaseException(ResponseCode.OPERATION_FAILED);
        // 若预约为上午且上午人已满
        if (Objects.equals(orderRequest.getTimeQuantum(), TimeQuantumEnum.MORNING.getCode()) &&
                Objects.equals(arrangementPO.getMorningTotalNumber(), arrangementPO.getMorningActualNumber()))
            throw new BaseException(ResponseCode.OPERATION_FAILED);
        // 若预约为下午且上午人已满
        if (Objects.equals(orderRequest.getTimeQuantum(), TimeQuantumEnum.AFTERNOON.getCode()) &&
                Objects.equals(arrangementPO.getAfternoonTotalNumber(), arrangementPO.getAfternoonActualNumber()))
            throw new BaseException(ResponseCode.OPERATION_FAILED);
        /**
         * 完成预约操作
         */
        // 1.修改Arrangement表
        if (Objects.equals(orderRequest.getTimeQuantum(), TimeQuantumEnum.MORNING.getCode()))
            arrangementPO.setMorningActualNumber(arrangementPO.getMorningActualNumber() + 1);
        if (Objects.equals(orderRequest.getTimeQuantum(), TimeQuantumEnum.AFTERNOON.getCode()))
            arrangementPO.setAfternoonActualNumber(arrangementPO.getAfternoonActualNumber() + 1);
        arrangementPOMapper.updateByPrimaryKeySelective(arrangementPO);
        // 2.新建order表项
        OrderPO orderPO = userOrderUtil.OrderRequestToOrderPo(orderRequest);
        orderPOMapper.insertSelective(orderPO);
        return orderPO;
    }
}
